# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# 忽略警告
import warnings

warnings.filterwarnings('ignore')

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号

# 1. 数据收集与预处理
# 1.1 数据加载
data = pd.read_csv('live_ecommerce_users.csv')

# 1.2 数据清洗
# 删除重复数据
data.drop_duplicates(inplace=True)

# 处理缺失值
# 删除缺失值较多的列
data.dropna(axis=1, thresh=len(data) * 0.7, inplace=True)  # 删除缺失值超过30%的列

# 对剩余列中的少量缺失值进行填充
for column in data.columns:
    if data[column].dtype == 'object':
        # 填充分类变量的缺失值
        data[column] = data[column].fillna(data[column].mode()[0])
    else:
        # 填充数值变量的缺失值
        data[column] = data[column].fillna(data[column].median())

# 1.3 数据类型转换
# 将分类变量转换为数值型
label_encoders = {}
categorical_columns = ['Gender', 'MaritalStatus', 'PreferedOrderCat', 'PreferredLoginDevice', 'CityTier']

for col in categorical_columns:
    if col not in data.columns:
        print(f"列名 '{col}' 在数据中不存在，跳过该列。")
        continue
    le = LabelEncoder()
    data[col] = le.fit_transform(data[col])
    label_encoders[col] = le

# 确保所有列都是数值型
data = data.select_dtypes(include=[np.number])

# 2. 数据分析与建模
# 2.1 探索性数据分析(EDA)
# 计算用户流失率
churn_rate = data['Churn'].mean()
print(f'用户流失率: {churn_rate:.2%}')

# 绘制用户流失分布图
plt.figure(figsize=(8, 6))
sns.countplot(x='Churn', data=data)
plt.title('用户流失分布')
plt.xlabel('是否流失')
plt.ylabel('用户数量')
plt.savefig('用户流失分布图.png')  # 保存图片
plt.show()

# 2.2 相关性分析
# 计算相关性矩阵
corr_matrix = data.corr()

# 绘制相关性热力图
plt.figure(figsize=(12, 10))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('特征相关性热力图')
plt.savefig('特征相关性热力图.png')  # 保存图片
plt.show()

# 筛选与用户流失高度相关的特征
relevant_features = corr_matrix[abs(corr_matrix['Churn']) > 0.1].index.tolist()
relevant_features.remove('Churn')
print('与用户流失高度相关的特征:', relevant_features)

# 2.3 模型建立
# 特征选择
X = data[relevant_features]
y = data['Churn']

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

# 使用随机森林模型
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)

# 模型评估
y_pred = rf_model.predict(X_test)
print('模型准确率:', accuracy_score(y_test, y_pred))
print('混淆矩阵:\n', confusion_matrix(y_test, y_pred))
print('分类报告:\n', classification_report(y_test, y_pred))

# 3. 结果解读与建议
# 特征重要性分析
feature_importances = pd.Series(rf_model.feature_importances_, index=relevant_features)
feature_importances = feature_importances.sort_values(ascending=False)

# 绘制特征重要性条形图
plt.figure(figsize=(10, 8))
sns.barplot(x=feature_importances.values, y=feature_importances.index)
plt.title('特征重要性分析')
plt.xlabel('重要性得分')
plt.ylabel('特征')
plt.savefig('特征重要性分析图.png')  # 保存图片
plt.show()

# 4. 数据可视化
# 可视化用户流失与关键特征的关系
for feature in relevant_features:
    plt.figure(figsize=(10, 6))
    sns.boxplot(x='Churn', y=feature, data=data)
    plt.title(f'用户流失与{feature}的关系')
    plt.xlabel('是否流失')
    plt.ylabel(feature)
    plt.savefig(f'用户流失与{feature}的关系图.png')  # 保存图片
    plt.show()